<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>留言板</title>
  <link rel="stylesheet" href="./index.css">
  <link rel="stylesheet" href="editormd/css/editormd.css" />
</head>

<body>
  <div class="main">
    <div class="instructions">
      <a href="https://gitee.com/zzwuweijun/learning_code/tree/master/_%E9%A1%B9%E7%9B%AE/留言板"
        style="text-decoration: none;">【源码】</a>
      留言板，有效期30天，具体用途，随你了~
    </div>
    <div class="centent_div" id="centent_div">
      <!-- <div id="test-editormd"> </div> -->
    </div>
    <div class="addEdit">
      <div class="addEdit_bu" id="addEdit_bu">+</div>
    </div>

    <div class="myEdit" id="myEdit">
      <div class="myEdit_button">
        <div class="button" id="quxiao">取消</div>
        <div class="button" id="qingkong">清空</div>
        <div class="button" id="tijioa">提交</div>
      </div>
      <div id="test-editor"> </div>
    </div>
  </div>

  <script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
  <script src="editormd/editormd.min.js"></script>
  <script type="text/javascript">
    let start = 0, end = 10
    window.onload = () => {
      bodyHeight();
      init(start, end, { startScroll: true })
    };

    function init(start, end, { startScroll = false, isScrollTop = true }) {
      fetch(`/getData?start=${start}&end=${end}`, {}).then(response => {
        if (response.status >= 200 && response.status < 300) { // 判断请求是否成功
          return response.json() // 得到 JSON 对象
        } else {
          throw new Error(response.statusText);
        }
      }).then(json => {
        if (json.success) {
          if (Array.isArray(json.data)) {
            let arr = json.data;
            if (arr.length == 0) noMoreFn(), scroll_centent_div(true);
            arr.forEach(element => {
              addEditDiv(JSON.parse(element), true, isScrollTop)
            });
            startScroll && scroll_centent_div();
            runtime = false;
          }
        }
      }).catch(err => {
        console.log('Request Failed', err)
      });
    }

    function addEditDiv(data, isInsertBefore = true, isScrollTop = true) {
      if (data.vavlidity) {
        var newElement = document.createElement('div');
        newElement.classList.add('centent_div_con')
        newElement.innerHTML = `
          <div id="${data.vavlidity}"></div>
          <div class="centent_div_fn">
            <div class="centent_div_fn_date">${format('YYYY/MM/DD hh:mm', data.createDate)}</div>
            <div class="centent_div_fn_exe">
              <div class="centent_div_fn_exe_copy myAnimation" onclick="copyFn(this,${data.vavlidity})"></div>
            </div>
          </div>
        `;
        var targetDiv = document.getElementById('centent_div');
        if (targetDiv) {
          // 使用 insertBefore 将新元素添加到目标元素的第一个子元素之前  
          // 如果没有子元素，则它将成为第一个子元素  
          // 注意：这里我们使用 targetDiv.firstChild，它可能是 null（如果没有子元素）  
          // 但 insertBefore 可以处理 null 作为参考节点，将其视为在元素末尾插入  
          if (targetDiv.firstChild && isInsertBefore) {
            targetDiv.insertBefore(newElement, targetDiv.firstChild);
          } else {
            targetDiv.appendChild(newElement);
          }
        }
        window[data.vavlidity] = editormd(data.vavlidity, {
          lineNumbers: false,
          atLink: true,
          markdown: data.centent, // 这是内容
          width: "100%",
          // height: 200 + "px",
          autoHeight: true,
          watch: 1,
          toolbar: 0,
          path: "editormd/lib/",
          onload: function () {
            try {
              // this.editor[0].style.height = "auto";
              // this.preview[0].style.height = this.preview[0].scrollHeight + 5 + "px";
              isInsertBefore || (this.setMarkdown(data.centent), scrollHeightFn());
              isScrollTop && $('#centent_div').scrollTop($('#centent_div')[0].scrollHeight);
            } catch (e) {
              console.log('使用delete删除style属性可能不被支持或没有效果');
            }
          }
        });
      }
    }

    // 添加，没有更多
    function noMoreFn() {
      var newElement = document.createElement('div');
      newElement.classList.add('noMOre');
      newElement.innerText = '没有更多了'
      var targetDiv = document.getElementById('centent_div');
      if (targetDiv) {
        if (targetDiv.firstChild) {
          targetDiv.insertBefore(newElement, targetDiv.firstChild);
        } else {
          targetDiv.appendChild(newElement);
        }
      }
    }

    // 初始化编辑的块
    var editorToServer = editormd("test-editor", {
      lineNumbers: true,
      markdown: "", // 这是内容
      width: "100%",
      // height: "calc(100% - 100px)",
      // autoHeight: true,
      path: "editormd/lib/",
      watch: 1,
      toolbar: 1,
      toolbarIcons: function () {
        return ["undo", "redo", "|", "bold", "hr", "link", "|", "h1", "h2", "h3", "h4"]
        // return ["undo", "redo", "|", "bold", "hr", "|", "watch", "|", "h1", "h2", "h3", "h4"]
      },
    });

    // 显示编辑
    document.getElementById('addEdit_bu').addEventListener('click', (event) => {
      document.getElementById('myEdit').style.zIndex = 99999;
    })
    // 取消
    let quxiaoFn = () => document.getElementById('myEdit').style.zIndex = -1;
    document.getElementById('quxiao').addEventListener('click', (event) => { quxiaoFn(); })
    // 清空
    let qingkongFn = () => editorToServer.setMarkdown(' ');
    document.getElementById('qingkong').addEventListener('click', (event) => { qingkongFn(); })
    // 提交
    document.getElementById('tijioa').addEventListener('click', (event) => {
      let centent = editorToServer.getMarkdown();
      if (!centent.trim()) return;
      let senData = { centent, vavlidity: vavlidityFn(), createDate: new Date().getTime() }
      fetch('/setData', {
        method: 'POST', // HTTP 请求的方法，POST、DELETE、PUT都在这个属性设置。
        headers: {	// 一个对象，用来定制 HTTP 请求的标头。
          "Content-type": "application/json;charset=utf-8",
        },
        body: JSON.stringify(senData),	// POST 请求的数据体。
      }).then(response => {
        return response.json() // 得到 JSON 对象
      }).then(json => {
        // console.log(senData);  // 得到最终结果。
        addEditDiv(senData, false);
        quxiaoFn();
        qingkongFn();
      }).catch(err => {
        console.log('Request Failed', err)
      });
    })


    // 滚出时触发事件
    let lastScrollTop = 0;
    let runtime = true;
    function centent_div_scroll() {
      let tt = document.getElementById('centent_div');
      var scrollTop = tt.pageYOffset || tt.scrollTop;
      // 判断滚动方向  
      if (scrollTop < lastScrollTop) {
        // 向上滚动  
        if (scrollTop <= 500 && !runtime) {
          start = end + 1;
          end += 10;
          runtime = true;
          init(start, end, { startScroll: false, isScrollTop: false });
        }
      }
      // 更新最后的滚动位置  
      lastScrollTop = scrollTop;
    }
    function scroll_centent_div(remove = false) {
      !remove && document.getElementById('centent_div').addEventListener('scroll', centent_div_scroll);
      remove && document.getElementById('centent_div').removeEventListener('scroll', centent_div_scroll);
    }

    // 滚动到底部
    let time = 0;
    function scrollHeightFn(outTime = 300) {
      clearTimeout(time);
      time = setTimeout(() => {
        $('#centent_div').scrollTop($('#centent_div')[0].scrollHeight);
      }, outTime);

    }

    // 点击一个就跳动一下
    function copyFn(event, id) {
      event.classList.add('bounce');
      // 监听动画结束事件  
      event.addEventListener('animationend', function (event) {
        if (event.animationName === 'bounce') { this.classList.remove('bounce'); }
      }, { once: true }); // { once: true } 确保事件监听器只触发一次  
      ;
      copyText(window[id].getMarkdown());
    }

    // 复制文本内容
    function copyText(text) {
      let inputDom = document.createElement('textarea');  // 创建一个textarea元素，使用input元素的话，换行会没有了
      inputDom.setAttribute('readonly', 'readonly'); // 防止手机上弹出软键盘
      inputDom.value = text; // 给input元素赋值
      document.body.appendChild(inputDom); // 添加到body
      inputDom.select(); //选中input元素的内容
      document.execCommand('Copy'); // 执行浏览器复制命令
      inputDom.style.display = 'none';
      inputDom.remove(); // 移除input元素
    }

    function lilneHeight(txt) {
      // 使用正则表达式匹配所有可能的换行符组合  
      let lines = txt.split(/\r?\n/);
      // 数组长度减一即为换行符的数量（因为最后一个元素之后没有换行符）  
      let newlineCount = lines.length - 1;
      return newlineCount;
    }

    // 计算有效期时间，默认有效期时长为30天
    function vavlidityFn() {
      return new Date().getTime() + 1000 * 60 * 60 * 24 * 30;
    }

    /**
    * 将指定日期时间或当前日期时间转换成指定的格式。
    * @fmt {String} 日期格式
    * @timestamp {Date} 标准时间。选填。
    * format("YYYY-MM-DD hh:mm:ss")
    */
    function format(fmt, timestamp) {
      const date = timestamp ? new Date(timestamp) : new Date()
      const o = {
        "Y+": date.getFullYear(),
        "M+": date.getMonth() + 1,     // 月
        "D+": date.getDate(),          // 日
        "h+": date.getHours(),         // 时
        "m+": date.getMinutes(),       // 分
        "s+": date.getSeconds(),       // 秒
        "W": date.getDay()             // 周
      }
      for (var k in o) {
        if (new RegExp("(" + k + ")").test(fmt)) {
          fmt = fmt.replace(RegExp.$1, () => {
            if (k === 'W') {                                    // 星期几
              const week = ['日', '一', '二', '三', '四', '五', '六']
              return week[o[k]]
            } else if (k === 'Y+' || RegExp.$1.length == 1) {    // 年份 or 小于10不加0
              return o[k]
            } else {
              return ("00" + o[k]).substr(("" + o[k]).length)  // 小于10补位0
            }
          })
        }
      }
      return fmt
    }

    // 计算body的高度
    function bodyHeight() {
      document.body.style.height = window.innerHeight + 'px';
      window.addEventListener('resize', function () {
        var newViewportHeight = window.innerHeight;
        document.body.style.height = newViewportHeight + 'px';
      });
    }

    // 监听页面上所有<a>标签的点击事件来拦截其默认行为，并在点击时通过window.open()方法在新的浏览器标签页中打开链接。如果页面中的a标签是动态添加的，你可能需要使用事件委托来确保新添加的a标签也能被监听
    document.body.addEventListener('click', function (event) {
      if (event.target.tagName.toLowerCase() === 'a') {
        event.preventDefault();
        window.open(event.target.getAttribute('href'), '_blank');
      }
    });
  </script>
</body>

</html>